package com.itwlj.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itwlj.constant.MessageConstant;
import com.itwlj.constant.MqConstant;
import com.itwlj.constant.StatusConstant;
import com.itwlj.context.BaseContext;
import com.itwlj.dto.CommentDTO;
import com.itwlj.dto.OrderDTO;
import com.itwlj.dto.OrderPageQueryDTO;
import com.itwlj.entity.*;
import com.itwlj.exception.CommentExistsException;
import com.itwlj.exception.InventoryNotEnoughException;
import com.itwlj.mapper.GoodsMapper;
import com.itwlj.mapper.OrderMapper;
import com.itwlj.mapper.SkuMapper;
import com.itwlj.result.PageResult;
import com.itwlj.service.AddressBookService;
import com.itwlj.service.CartService;
import com.itwlj.service.OrderService;
import com.itwlj.service.SkuService;
import com.itwlj.vo.OrderVO;
import com.itwlj.vo.OrdersPreviewVO;
import com.itwlj.vo.SummaryVO;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 订单业务层
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private CartService cartService;
    @Autowired
    private AddressBookService addressService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private SkuMapper skuMapper;
    @Autowired
    private SkuService skuService;
    @Autowired
    private GoodsMapper goodsMapper;

    @Value("${mall.postFee}")
    private BigDecimal postFee;
    @Value("${mall.countdown}")
    private Integer countdown;

    /**
     * 订单分页查询
     *
     * @param orderPageQueryDTO
     * @return
     */
    public PageResult pageQuery(OrderPageQueryDTO orderPageQueryDTO) {
        orderPageQueryDTO.setIsDelete(StatusConstant.NOT_DELETED);
        PageHelper.startPage(orderPageQueryDTO.getPage(), orderPageQueryDTO.getPageSize());
        Page<OrderVO> page = orderMapper.pageQuery(orderPageQueryDTO);
        page.forEach(orderVO -> {
            orderVO.setOrderGoodsList(orderMapper.getOrderGoods(orderVO.getId()));
        });
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 订单批量删除(逻辑删除)
     *
     * @param ids
     */
    public void softDeleteBatch(List<Long> ids) {
        System.out.println(ids);
        orderMapper.softDeleteBatch(ids, StatusConstant.DELETED);
    }

    /**
     * 根据id修改商品
     *
     * @param orderDTO
     */
    public void update(OrderDTO orderDTO) {
        Order order = new Order();
        BeanUtils.copyProperties(orderDTO, order);
        orderMapper.update(order);
    }

    /**
     * 获取地址和商品信息
     *
     * @return
     */
    public OrdersPreviewVO getOrdersPreview() {
        List<Cart> cartList = cartService.getByUserId();

        SummaryVO amountSummary = getAmountSummary(cartList);

        OrdersPreviewVO ordersPreviewVO = OrdersPreviewVO.builder()
                .defaultAddress(addressService.getDefaultAddress())
                .orderGoodsList(buildOrderGoodsVOList(cartList))
                .summary(amountSummary)
                .build();

        return ordersPreviewVO;
    }

    /**
     * 新增订单
     *
     * @param orderDTO
     * @return
     */
    public Long insert(OrderDTO orderDTO) {

        List<OrderGoods> orderGoodsList = orderDTO.getOrderGoodsList();
        //扣减库存
        orderGoodsList.forEach(orderGoods -> {
            Long skuId = orderGoods.getSkuId();
            Long count = (long) orderGoods.getCount();

            Sku sku = skuMapper.getById(skuId);
            if (sku.getInventory() < count) {
                throw new InventoryNotEnoughException(MessageConstant.INVENTORY_NOT_ENOUGH);
            }
            skuService.deductInventory(skuId, count);
        });

        Order order = new Order();
        BeanUtils.copyProperties(orderDTO, order);

        List<Cart> cartList = cartService.getByUserId();
        SummaryVO amountSummary = getAmountSummary(cartList);

        AddressBook addressBook = addressService.getById(orderDTO.getAddressId());

        //封装order对象
        order.setUserId(BaseContext.getCurrentId());
        order.setCreateTime(LocalDateTime.now());
        order.setOrderState(StatusConstant.ORDER_UNPAID);
        order.setTotalMoney(amountSummary.getTotalPayPrice());
        order.setTotalNum(amountSummary.getGoodsCount());
        order.setReceiver(addressBook.getReceiver());
        order.setReceiverContact(addressBook.getContact());
        order.setReceiverAddress(addressBook.getAddress());
        order.setIsDelete(StatusConstant.NOT_DELETED);
        orderMapper.insert(order);

        Long orderId = order.getId();

        //插入订单商品
        orderGoodsList.forEach(orderGoods -> {
            orderGoods.setOrderId(orderId);
            orderMapper.insertOrderGoods(orderGoods);
        });

        //发送消息到交换机
        rabbitTemplate.convertAndSend(
                MqConstant.ORDER_TIMEOUT_DELAY_EXCHANGE,
                MqConstant.ORDER_TIMEOUT_DELAY_ROUTING_KEY,
                orderId,
                message -> {
                    message.getMessageProperties().setDelay(countdown);
                    return message;
                }
        );
        return orderId;
    }

    /**
     * 根据id查询订单
     *
     * @param id
     * @return
     */
    public OrderVO getById(Long id) {
        Order order = orderMapper.getById(id);
        List<OrderGoods> orderGoodsList = orderMapper.getOrderGoods(order.getId());

        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(order, orderVO);
        orderVO.setOrderGoodsList(orderGoodsList);

        return orderVO;
    }

    /**
     * 订单发货
     *
     * @param id
     */
    public void shipOrder(Long id) {
        if (!Objects.equals(orderMapper.getById(id).getOrderState(), StatusConstant.ORDER_PAID)) {
            return;
        }

        Order order = new Order();
        order.setId(id);
        order.setOrderState(StatusConstant.ORDER_SHIPPED);
        order.setConsignTime(LocalDateTime.now());

        orderMapper.update(order);
    }

    /**
     * 订单运输
     *
     * @param id
     */
    public void transportOrder(Long id) {
        if (!Objects.equals(orderMapper.getById(id).getOrderState(), StatusConstant.ORDER_SHIPPED)) {
            return;
        }

        Order order = new Order();
        order.setId(id);
        order.setOrderState(StatusConstant.ORDER_IN_TRANSIT);

        orderMapper.update(order);
    }

    /**
     * 取消订单
     *
     * @param id
     */
    public void cancelOrder(Long id) {
        Order order = new Order();
        order.setId(id);
        order.setOrderState(StatusConstant.ORDER_CLOSE);

        orderMapper.update(order);
    }

    /**
     * 用户取消订单
     *
     * @param id
     */
    public void userCancelOrder(Long id) {
        Order order = new Order();
        order.setId(id);
        order.setOrderState(StatusConstant.ORDER_CANCELING);

        orderMapper.update(order);
    }

    /**
     * 确认收货
     *
     * @param id
     */
    public void confirmReceive(Long id) {
        if (!Objects.equals(orderMapper.getById(id).getOrderState(), StatusConstant.ORDER_RECEIVED)) {
            return;
        }

        Order order = new Order();
        order.setId(id);
        order.setOrderState(StatusConstant.ORDER_COMPLETED);

        orderMapper.update(order);
    }

    /**
     * 评论商品
     *
     * @param commentDTO
     */
    public void commentOrder(CommentDTO commentDTO) {
        if (!goodsMapper.getCommentByOrderId(commentDTO.getOrderId()).isEmpty()){
            throw new CommentExistsException(MessageConstant.COMMENT_EXISTS);
        }

        Sku sku = skuMapper.getById(commentDTO.getSkuId());
        Comment comment = new Comment();
        BeanUtils.copyProperties(commentDTO,comment);
        comment.setGoodsId(sku.getGoodsId());

        goodsMapper.insertComment(comment);
    }

    /**
     * 获取金额明细
     *
     * @return
     */
    private SummaryVO getAmountSummary(List<Cart> cartList) {

        Integer goodsCount = 0;
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (Cart cart : cartList) {
            goodsCount += cart.getCount();
            totalPrice = totalPrice.add(cart.getPrice().multiply(new BigDecimal(cart.getCount())));
        }
        BigDecimal totalPayPrice = totalPrice.add(postFee);

        SummaryVO summaryVO = new SummaryVO();
        summaryVO.setGoodsCount(goodsCount);
        summaryVO.setTotalPrice(totalPrice);
        summaryVO.setPostFee(postFee);
        summaryVO.setTotalPayPrice(totalPayPrice);

        return summaryVO;
    }

    /**
     * 将List<Cart>封装成List<OrderGoods>的方法
     *
     * @param cartList
     * @return
     */
    private List<OrderGoods> buildOrderGoodsVOList(List<Cart> cartList) {
        List<OrderGoods> orderGoodsList = new ArrayList<>();
        cartList.forEach(cart -> {
            OrderGoods orderGoods = OrderGoods.builder()
                    .id(cart.getId())
                    .skuId(cart.getSkuId())
                    .picture(cart.getPicture())
                    .name(cart.getName())
                    .attrsText(cart.getAttrsText())
                    .price(cart.getPrice())
                    .count(cart.getCount())
                    .build();

            orderGoodsList.add(orderGoods);
        });

        return orderGoodsList;
    }
}
